package com.sihan.framework.etm.service.impl;

import com.framework.model.ApiResult;
import com.framework.model.PageResult;
import com.framework.mybatis.service.impl.BaseServiceImpl;
import com.framework.util.PageUtils;
import com.github.pagehelper.PageHelper;
import com.sihan.framework.etm.common.CacheOperatorInfo;
import com.sihan.framework.etm.common.PageRequest;
import com.sihan.framework.etm.common.cache.LocalCache;
import com.sihan.framework.etm.common.util.*;
import com.sihan.framework.etm.dto.*;
import com.sihan.framework.etm.dto.business.DeviceMountDTO;
import com.sihan.framework.etm.entity.EtmDeviceRecord;
import com.sihan.framework.etm.entity.WorkTicket;
import com.sihan.framework.etm.entity.baseData.DeviceModel;
import com.sihan.framework.etm.entity.baseData.EtmDeviceMount;
import com.sihan.framework.etm.entity.business.CollectionRecord;
import com.sihan.framework.etm.entity.business.DeviceStatistics;
import com.sihan.framework.etm.enums.DeviceType;
import com.sihan.framework.etm.mapper.EtmDeviceMountMapper;
import com.sihan.framework.etm.mapper.WorkTicketMapper;
import com.sihan.framework.etm.mapper.baseData.DeviceMapper;
import com.sihan.framework.etm.mapper.baseData.EtmDeviceRecordMapper;
import com.sihan.framework.etm.service.EtmDeviceMountService;
import com.sihan.framework.etm.service.PushAnomalyRecordService;
import com.sihan.framework.etm.vo.baseData.DeviceVO;
import com.sihan.framework.etm.mapper.business.ToolPositionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.xml.crypto.Data;
import java.math.BigDecimal;
import java.net.BindException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;

/**
 * (EtmDeviceMount)表服务实现类
 *
 * @author makejava
 * @since 2022-05-20 16:04:48
 */
@Slf4j
@Service("etmDeviceMountService")
public class EtmDeviceMountServiceImpl extends BaseServiceImpl<EtmDeviceMount, String> implements EtmDeviceMountService {

    public Hashtable<String, Long> abnormalMap = new Hashtable<String, Long>();
    Monitor monitors = new Monitor();
    Thread monitor;
    @Value("${device-InterruptDuration}")
    private Integer time;
    @Autowired
    private EtmDeviceMountMapper etmDeviceMountMapper;
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private WorkTicketMapper workTicketMapper;
    @Autowired
    private PushAnomalyRecordService pushAnomalyRecordService;
    @Autowired
    private ToolPositionMapper toolPositionMapper;

    @Autowired
    private EtmDeviceRecordMapper etmDeviceRecordMapper;

    //private final AbnormalMonitor abnormalMonitor = new AbnormalMonitor();


    public EtmDeviceMountServiceImpl() {
        startThread();
    }

    /**
     * 获取指定时间后一天
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date DeforeOneHourToNowDate(String date) throws ParseException {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'+'SSSS");
        Calendar calendar = Calendar.getInstance();
        /* HOUR_OF_DAY 指示一天中的小时 */
        calendar.setTime(simpleDateFormat.parse(date));
        calendar.add(Calendar.HOUR_OF_DAY, -1);
        return calendar.getTime();
    }

    /**
     * 根据 record 与 device 对工器具工作状态 做记录
     *
     * @param record
     * @param device
     */
    @Override
    public void insertDeviceMount(EtmDeviceRecord record, DeviceModel device, Date date) {
        String msg = "";
        String topic = "ABNORMITY";
        System.out.println("异常类型" + record.getAlarm());
        Boolean hitchA = record.getHitchA();
        if (null == hitchA) {
            hitchA = false;
        }
        Boolean hitchB = record.getHitchB();
        if (null == hitchB) {
            hitchB = false;
        }
        Boolean hitchC = record.getHitchC();
        if (null == hitchC) {
            hitchC = false;
        }
        Boolean d1 = record.getG1();
        Boolean d2 = record.getG2();
        Boolean d3 = record.getG3();
        if (null == d1) {
            d1 = false;
        }if (null == d2) {
            d2 = false;
        }if (null == d3) {
            d3 = false;
        }


        EtmDeviceMount deviceMount = null;
        //由于设备无异常为 0 数据库无异常为 1 所以进行转换
        if (device.getTypeId().equals(DeviceType.GroundWire)) {
            //Alarm 可能为空 为空默认为无异常
            if (null == record.getAlarm()) {
                record.setAlarm(1);
            } else if (0 == record.getAlarm()) {
                if (hitchA && hitchB && hitchC) {
                    record.setAlarm(1);
                }
            } else if (314 == record.getAlarm()) {
                if (hitchA && hitchB && hitchC) {
                    record.setAlarm(1);
                } else {
                    record.setAlarm(0);
                }
            } else if (321 == record.getAlarm()) {
                //321 表示接地端已挂接
                if (hitchA && hitchB && hitchC) {
                    record.setAlarm(1);
                } else {
                    record.setAlarm(0);
                }
            } else if (1 == record.getAlarm() && !(hitchA && hitchB && hitchC)) {
                record.setAlarm(0);
            }
            if (abnormalMap.containsKey("hitch" + device.getId()) && (hitchA | hitchB | hitchC)) {
                if (0 == record.getAlarm()) {
                    record.setAlarm(323);
                } else {
                    // 出现异常挂载 直接删除监听key
                    abnormalMap.remove("hitch" + device.getId());
                }
            }
            deviceMount = etmDeviceMountMapper.selectByDeviceIdEtmDeviceMount(device.getId(), record.getAlarm());
        } else if (device.getTypeId().equals(DeviceType.SDGroundWire)) {
            //Alarm 可能为空 为空默认为无异常
            if (null == record.getAlarm()) {
                record.setAlarm(1);
            } else if (0 == record.getAlarm()) {
                if (hitchA && hitchB && hitchC) {
                    record.setAlarm(1);
                }
            } else if (321 == record.getAlarm()) {
                //321 表示接地端已挂接
                if (hitchA && hitchB && hitchC) {
                    record.setAlarm(1);
                } else {
                    record.setAlarm(0);
                }
            } else if (1 == record.getAlarm() && !(hitchA && hitchB && hitchC)) {
                record.setAlarm(0);
            }

            deviceMount = etmDeviceMountMapper.selectByDeviceIdEtmDeviceMount(device.getId(), record.getAlarm());
        } else if (device.getTypeId().equals(DeviceType.SafetyHat)) {
            deviceMount = etmDeviceMountMapper.selectByDeviceIdEtmDeviceMount(device.getId(), null);
        }
        switch (device.getTypeId()) {
            //智能接地线
            case DeviceType.GroundWire:
                String s = (hitchA ? "1" : "0") + "," + (hitchB ? "1" : "0") + "," + (hitchC ? "1" : "0");

                if (null != deviceMount) {
                    deviceMount.setHitchAbc(s);
                    if (null != device.getInitialLat()) {
                        deviceMount.setLat(device.getInitialLat().toString());
                    }
                    if (null != device.getInitialLng()) {
                        deviceMount.setLng(device.getInitialLng().toString());
                    }
                    deviceMount.setHeight(device.getInitialHeight());
                    //正常挂载状态 三项挂载齐全
                    if (hitchA && hitchB && hitchC) {

                        deviceMount.setMountState(1);
                        if (null == deviceMount.getStartTime()) {
                            deviceMount.setStartTime(record.getCreateTime());
                        }
                        //挂接中改为正常挂载
                        if (323 == deviceMount.getMountType()) {
                            deviceMount.setMountType(1);
                        }
                        deviceMount.setEndTime(record.getCreateTime());
                        deviceMount.setMountType(record.getAlarm());
                        etmDeviceMountMapper.updateAll(deviceMount);
                        //删除监听key
                        abnormalMap.remove("hitch" + device.getId());
                        log.info("设备：" + deviceMount.getDeviceCode() + "挂接完成;" + record.getCreateTime());
                    } else if (hitchA || hitchB || hitchC) {
                        //缺项 有两种情况 可能是正在取或者挂接地线过程中 还有一种就是一直就缺项工作
                        if (!abnormalMap.containsKey("hitch" + device.getId())) {
                            abnormalMap.put("hitch" + device.getId(), new Date().getTime());
                            if (0 == record.getAlarm()) {
                                record.setAlarm(323);
                            }
                        } else {
                            //判断时间
                            Long aLong = abnormalMap.get("hitch" + device.getId());
                            if (date.getTime() - aLong > 180000) {
                                if (hitchA && hitchB && hitchC) {
                                    record.setAlarm(1);
                                } else {
                                    record.setAlarm(0);
                                }
                            }
                        }
                        deviceMount.setMountType(record.getAlarm());
                        if (null == deviceMount.getStartTime()) {
                            deviceMount.setStartTime(record.getCreateTime());
                        }
                        deviceMount.setEndTime(record.getCreateTime());
                        etmDeviceMountMapper.updateAll(deviceMount);
                    } else {
                        //三项均无挂接时 修改设备挂接状态
                        etmDeviceMountMapper.updateBydeviceId(deviceMount.getDeviceId());
                        etmDeviceMountMapper.deleteByMountType(device.getId());
                        etmDeviceMountMapper.updateBydeviceIdOne(deviceMount.getDeviceId(), record.getCreateTime());
                        abnormalMap.remove("hitch" + device.getId());
                        log.info("设备：" + deviceMount.getDeviceCode() + "结束挂载;" + record.getCreateTime());
                    }
                    if (null != record.getAlarm()) {
                        if (record.getAlarm() != 1 && record.getAlarm() != 323) {
                            msg = deviceMapper.getExceptionCode(record.getAlarm());
                            topic = topic + "-" + deviceMount.getId();
                        }
                    }
                    //JudgmentException(deviceMount);
                } else {
                    EtmDeviceMount etmDeviceMount = new EtmDeviceMount();
                    if (null != device.getInitialLat()) {
                        etmDeviceMount.setLat(device.getInitialLat().toString());
                    }
                    if (null != device.getInitialLng()) {
                        etmDeviceMount.setLng(device.getInitialLng().toString());
                    }
                    if (null != device.getInitialHeight()) {
                        etmDeviceMount.setHeight(device.getInitialHeight());
                    }
                    etmDeviceMount.setDeviceTypeId(device.getTypeId());
                    etmDeviceMount.setDeviceId(device.getId());
                    etmDeviceMount.setDeviceCode(device.getCode());
                    etmDeviceMount.setHitchAbc(s);
                    etmDeviceMount.setMountState(1);
                    //挂载状态分析 三项全为true 正常挂载
                    if (hitchA && hitchB && hitchC && d1 && d2 && d3) {
                        etmDeviceMount.setMountType(record.getAlarm());
                        etmDeviceMount.setStartTime(record.getCreateTime());
                        etmDeviceMount.setEndTime(record.getCreateTime());
                        log.info("设备：" + device.getCode() + "完成挂载;" + record.getCreateTime());
                        abnormalMap.remove("hitch" + device.getId());
                        etmDeviceMountMapper.insertAll(etmDeviceMount);
                    } else if (hitchA || hitchB || hitchC || d1 || d2 || d3) {
                        //缺项 异常挂载
                        //判断是否存在异常
                        if (!abnormalMap.containsKey("hitch" + device.getId())) {
                            abnormalMap.put("hitch" + device.getId(), new Date().getTime());
                            if (0 == record.getAlarm()) {
                                record.setAlarm(323);
                            }
                        }
                        etmDeviceMount.setMountType(record.getAlarm());
                        etmDeviceMount.setStartTime(record.getCreateTime());
                        etmDeviceMount.setEndTime(record.getCreateTime());
                        log.info("设备：" + device.getCode() + "开始挂载;" + record.getCreateTime());
                        etmDeviceMountMapper.insertAll(etmDeviceMount);
                    } else {
                        //三项均无挂载 结束挂载
                        etmDeviceMountMapper.updateBydeviceId(device.getId());
                        etmDeviceMountMapper.deleteByMountType(device.getId());
                        abnormalMap.remove("hitch" + device.getId());
                    }
                    //JudgmentException(etmDeviceMount);
                }
                break;
            case DeviceType.SDGroundWire:{
                String s1 = (hitchA ? "1" : "0") + "," + (hitchB ? "1" : "0") + "," + (hitchC ? "1" : "0");

                String  ground = (d1 ? "1" : "0") + "," + (d2 ? "1" : "0") + "," + (d3 ? "1" : "0");

                if (null != deviceMount) {
                    deviceMount.setHitchAbc(s1);
                    deviceMount.setGround(ground);
                    if (null != device.getInitialLat()) {
                        deviceMount.setLat(device.getInitialLat().toString());
                    }
                    if (null != device.getInitialLng()) {
                        deviceMount.setLng(device.getInitialLng().toString());
                    }
                    deviceMount.setHeight(device.getInitialHeight());
                    //正常挂载状态 三项挂载齐全
                    if (hitchA && hitchB && hitchC) {

                        deviceMount.setMountState(1);
                        if (null == deviceMount.getStartTime()) {
                            deviceMount.setStartTime(record.getCreateTime());
                        }
                        //挂接中改为正常挂载
                        if (323 == deviceMount.getMountType()) {
                            deviceMount.setMountType(1);
                        }
                        deviceMount.setEndTime(record.getCreateTime());
                        deviceMount.setMountType(record.getAlarm());
                        etmDeviceMountMapper.updateAll(deviceMount);
                        //删除监听key
                        abnormalMap.remove("hitch" + device.getId());
                        log.info("设备：" + deviceMount.getDeviceCode() + "挂接完成;" + record.getCreateTime());
                    } else if (hitchA || hitchB || hitchC) {

                        deviceMount.setMountType(record.getAlarm());
                        if (null == deviceMount.getStartTime()) {
                            deviceMount.setStartTime(record.getCreateTime());
                        }
                        deviceMount.setEndTime(record.getCreateTime());
                        etmDeviceMountMapper.updateAll(deviceMount);
                    } else {
                        //三项均无挂接时 修改设备挂接状态
                        etmDeviceMountMapper.updateBydeviceId(deviceMount.getDeviceId());
                        etmDeviceMountMapper.deleteByMountType(device.getId());
                        etmDeviceMountMapper.updateBydeviceIdOne(deviceMount.getDeviceId(), record.getCreateTime());
                        abnormalMap.remove("hitch" + device.getId());
                        log.info("设备：" + deviceMount.getDeviceCode() + "结束挂载;" + record.getCreateTime());
                    }
                    if (null != record.getAlarm()) {
                        if (record.getAlarm() != 1 && record.getAlarm() != 323) {
                            msg = deviceMapper.getExceptionCode(record.getAlarm());
                            topic = topic + "-" + deviceMount.getId();
                        }
                    }
                    //JudgmentException(deviceMount);
                } else {
                    EtmDeviceMount etmDeviceMount = new EtmDeviceMount();
                    if (null != device.getInitialLat()) {
                        etmDeviceMount.setLat(device.getInitialLat().toString());
                    }
                    if (null != device.getInitialLng()) {
                        etmDeviceMount.setLng(device.getInitialLng().toString());
                    }
                    if (null != device.getInitialHeight()) {
                        etmDeviceMount.setHeight(device.getInitialHeight());
                    }
                    etmDeviceMount.setDeviceTypeId(device.getTypeId());
                    etmDeviceMount.setDeviceId(device.getId());
                    etmDeviceMount.setDeviceCode(device.getCode());
                    etmDeviceMount.setHitchAbc(s1);
                    etmDeviceMount.setGround(ground);
                    etmDeviceMount.setMountState(1);
                    //挂载状态分析 三项全为true 正常挂载
                    if (hitchA && hitchB && hitchC) {
                        etmDeviceMount.setMountType(record.getAlarm());
                        etmDeviceMount.setStartTime(record.getCreateTime());
                        etmDeviceMount.setEndTime(record.getCreateTime());
                        log.info("设备：" + device.getCode() + "完成挂载;" + record.getCreateTime());
                        abnormalMap.remove("hitch" + device.getId());
                        etmDeviceMountMapper.insertAll(etmDeviceMount);
                    } else if (hitchA || hitchB || hitchC) {
                        //缺项 异常挂载
                        //判断是否存在异常
                        etmDeviceMount.setMountType(record.getAlarm());
                        etmDeviceMount.setStartTime(record.getCreateTime());
                        etmDeviceMount.setEndTime(record.getCreateTime());
                        log.info("设备：" + device.getCode() + "开始挂载;" + record.getCreateTime());
                        etmDeviceMountMapper.insertAll(etmDeviceMount);
                    } else {
                        //三项均无挂载 结束挂载
                        etmDeviceMountMapper.updateBydeviceId(device.getId());
                        etmDeviceMountMapper.deleteByMountType(device.getId());
                        abnormalMap.remove("hitch" + device.getId());
                    }
                    //JudgmentException(etmDeviceMount);
                }
                break;
            }
            case DeviceType.SafetyHat: {
                if (null != deviceMount) {
                    if (record.getAlarm() == 1) {
                        deviceMount.setEndTime(new Date());
                        msg = "安全帽-近电告警";
                        etmDeviceMountMapper.updateAll(deviceMount);
                    } else {
                        deviceMount.setEndTime(new Date());
                        //结束异常
                        etmDeviceMountMapper.updateBydeviceId(device.getId());
                    }
                    break;
                } else {
                    if (record.getAlarm() == 1) {
                        EtmDeviceMount etmDeviceMount = InitializeDeviceModel(device, date);
                        etmDeviceMount.setMountType(411);
                        etmDeviceMount.setMountState(1);
                        msg = "安全帽-近电告警";
                        etmDeviceMountMapper.insertAll(etmDeviceMount);
                    } else {
                        //结束异常
                        etmDeviceMountMapper.updateBydeviceId(device.getId());
                    }
                    break;
                }
            }
            case DeviceType.WarningSign: {
                EtmDeviceMount etmDeviceMount = InitializeDeviceModel(device, date);
                //标识牌 有电 1 无电 0
                if (record.getAlarm() == 0) {
                    etmDeviceMount.setMountType(1);
                } else if (record.getAlarm() == 1) {
                    etmDeviceMount.setMountType(421);
                    msg = "标识牌-有电危险";
                } else if (record.getAlarm() == 422) {
                    etmDeviceMount.setMountType(422);
                    msg = "标识牌-跌落告警";
                }
                etmDeviceMountMapper.insertAll(etmDeviceMount);
                break;
            }
        }
        if ("低".equals(QuantityUtils.powerToJudge(device.getVoltage()))) {
            pushAnomalyRecordService.addPushRecord(device, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(record.getCreateTime()), "LOWBATTERY", "电池电量低,请及时充电！");

        }
        if (!"".equals(msg)) {
            pushAnomalyRecordService.addPushRecord(device, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(record.getCreateTime()), topic, msg);
        }
    }

    /**
     * 初始化DeviceModel
     *
     * @param device
     * @return
     */
    private EtmDeviceMount InitializeDeviceModel(DeviceModel device,Date date) {
        EtmDeviceMount etmDeviceMount = new EtmDeviceMount();
        etmDeviceMount.setDeviceTypeId(device.getTypeId());
        etmDeviceMount.setDeviceId(device.getId());
        etmDeviceMount.setDeviceCode(device.getCode());
        etmDeviceMount.setHitchAbc(null);
        etmDeviceMount.setStartTime(date);
        etmDeviceMount.setEndTime(date);
        etmDeviceMount.setMountState(0);
        if (null != device.getInitialLat()) {
            etmDeviceMount.setLat(device.getInitialLat().toString());
        }
        if (null != device.getInitialLng()) {
            etmDeviceMount.setLng(device.getInitialLng().toString());
        }
        if (null != device.getInitialHeight()) {
            etmDeviceMount.setHeight(device.getInitialHeight());
        }
        return etmDeviceMount;
    }

    /**
     * 位置偏移警报判断 异常码331
     * 通信中断警报判断 异常码321
     */
    private void JudgmentException(EtmDeviceMount etmDeviceMount) {
        if (null != etmDeviceMount) {

            //判断是否是异常状态
            if (null != etmDeviceMount.getMountType() && etmDeviceMount.getMountType() != 1) {
                /*
                 * 处于异常状态时 判断信号是否中断
                 * 一次挂接只生成一次信号中断报警 以及异常弹窗
                 */
                abnormalMap.put(etmDeviceMount.getDeviceId(), new Date().getTime());
            } else {
                //设备不处于异常状态 在删除kay监听
                abnormalMap.remove(etmDeviceMount.getDeviceId());
            }
            if (null != etmDeviceMount.getMountState() && etmDeviceMount.getMountState() != 0) {
                /*处于挂接状态时 判断位置是否偏移
                 * 1.先查看是否绑定工作票 是否处于未未归还状态
                 * 2.绑定工作票后 根据工作票标点与当前定位位置判断是否超出规定偏移值
                 * 3.如果超出规定偏移值，则生成异常记录 并推送异常弹窗
                 * 4.一次挂接只生成一次位置偏移报警 以及异常弹窗
                 */
                //mount = etmDeviceMountMapper.selectByDeviceIdEtmDeviceMount(etmDeviceMount.getDeviceId(),331);
                WorkTicketDTO dto = workTicketMapper.findByDevId(etmDeviceMount.getDeviceId());
                //判断是否绑定工作票
                if (null != dto && null != dto.getLngLat()) {
                    String[] split = dto.getLngLat().split(";");
                    Boolean val = true;
                    for (String s : split) {
                        String[] split1 = s.split(",");
                        //偏移值 0.6米
                        if (LocationUtils.OffsetOrNot(Double.parseDouble(etmDeviceMount.getLng()),
                                Double.parseDouble(etmDeviceMount.getLat()),
                                Double.parseDouble(split1[1]),
                                Double.parseDouble(split1[0]),
                                0.6)) {
                            val = false;
                        }
                    }
                    if (val) {
                        AddAbnormal(etmDeviceMount.getDeviceId(), 331);
                    }
                }
            }

        }
    }

    /***
     * 根据设备id添加 异常
     * @param devId
     */
    public void AddAbnormal(String devId, Integer alarm) {
        //判断当前设备挂接是否存在相同异常
        EtmDeviceMount etmDeviceMount = etmDeviceMountMapper.selectByDeviceIdEtmDeviceMount(devId, alarm);
        if (null == etmDeviceMount) {
            DeviceModel device = deviceMapper.selectById(devId);
            String topic = "ABNORMITY";
            String msg = "";
            EtmDeviceMount etmDeviceMount1 = etmDeviceMountMapper.selectByDeviceId(devId);
            if (etmDeviceMount1.getMountState() == 0) {
                return;
            }
            etmDeviceMount1.setId(null);
            etmDeviceMount1.setStartTime(new Date());
            etmDeviceMount1.setEndTime(new Date());
            etmDeviceMount1.setMountType(alarm);
            etmDeviceMountMapper.insert(etmDeviceMount1);
            if (331 == alarm) {
                msg = "位置偏移告警";
            }
            if (321 == alarm) {
                msg = "信号中断告警";
            }
            if (0 == alarm) {
                msg = "挂接异常(缺项挂接)";
            }
            topic = topic + "-" + etmDeviceMount1.getId();
            pushAnomalyRecordService.addPushRecord(device, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), topic, msg);
            //删除监听key
            abnormalMap.remove(devId);
        }else {
            etmDeviceMount.setEndTime(new Date());
            etmDeviceMountMapper.updateAll(etmDeviceMount);
        }
    }

    /**
     * 工器具当前使用状态统计
     *
     * @param orgId 登录用户OrgId
     */
    @Override
    public Map<String, Integer> getDevState(String orgId) {
        HashMap<String, Integer> map = new HashMap<>();
        //xm:休眠 hx：唤醒 gj：挂接
        map.put("gj", 0);
        map.put("hx", 0);
        map.put("xm", 0);
        try {
            //根据登录用户 OrgId 查询设备 统计设备状态
            List<DeviceStatistics> ls = deviceMapper.getLastInsert(orgId);
            if (null != ls && ls.size()>0) {
                return this.deviceDataDis(ls, map);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 首页异常记录数量查询
     *
     * @return
     */
    @Override
    public Map<String, Integer> getDevStateMap() {
        HashMap<String, Integer> map = new HashMap<>();
        String orgIds = (String) CacheOperatorInfo.getMapValue(EtmWebUtil.userId(), null);
        if (null == orgIds) {
            map.put("gjyc", 0);
            map.put("aqmyc", 0);
            map.put("dlyc", 0);
            map.put("jspyc", 0);
            return map;
        }
        //gjyc:设备当前时间内的异常次数 dlyc：设备当前时间的电量异常
        Date endTime = new Date();
        Calendar calendar = Calendar.getInstance();
        /* HOUR_OF_DAY 指示一天中的小时 */
        calendar.setTime(endTime);
        calendar.add(Calendar.HOUR, -2);
        Date startTime = calendar.getTime();

        List<GetAllDeviceAlarmDTO> aqmyc = etmDeviceMountMapper.getAllDeviceAlarm(
                null,
                null,
                null,
                orgIds.split(","),
                null,
                startTime,
                endTime,
                null,
                DeviceType.SafetyHat);
        List<GetAllDeviceAlarmDTO> gjyc = etmDeviceMountMapper.getAllDeviceAlarm(
                null,
                null,
                null,
                orgIds.split(","),
                null,
                startTime,
                endTime,
                null,
                DeviceType.GroundWire);
        int lowBattery = 0;
        /**电池电量低于电量预警阀值视为低电量*/
        List<DeviceRecordDTO> li = deviceMapper.getDevAbnormalelectricQuantity(orgIds.split(","),
                null,
                null,
                null, null);

        map.put("gjyc", gjyc.size());
        map.put("aqmyc", aqmyc.size());
        map.put("dlyc", li.size());
        map.put("jspyc", 0);
        return map;
    }

    /**
     * 工器具使用次数排名
     *
     * @param OrgId
     * @return
     */
    @Override
    public List<DeviceMountDTO> usingAstate(String OrgId) {
        try {
            //根据登录用户 OrgId 查询设备 统计设备使用次数
            List<DeviceMountDTO> ls = etmDeviceMountMapper.selectByDeviceIdGetMountType(OrgId, null);
            if (null != ls || 0 != ls.size()) {
                return ls;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 挂载异常次数
     *
     * @param OrgId
     * @return
     */
    @Override
    public List<DeviceMountDTO> mountTheAbnormal(String OrgId) {
        try {
            //根据登录用户 OrgId 查询设备 统计设备使用次数   mountType 0为异常挂载 1为正常挂载
            List<DeviceMountDTO> ls = etmDeviceMountMapper.selectByDeviceIdGetMountType(OrgId, 0);
            return ls;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<EtmDeviceMount> getEtmDeviceMountList(String deviceId, Data startTime, Data endTime, String OrgId) {

        return null;
    }

    /**
     * 获取单个设备的异常记录
     *
     * @return
     */
    @Override
    public PageResult<EtmDeviceMountDTO> pageDeviceOneMount(MountDTO dto) {
        PageHelper.startPage(dto);
        Date startTheReturn = null;
        Date endTheReturn = null;
        try {

            if (null != dto.getStartDate() && "" != dto.getStartDate()) {
                startTheReturn = new SimpleDateFormat("yyyy-MM-dd").parse(dto.getStartDate());
            }
            if (null != dto.getEndDate() && "" != dto.getEndDate()) {
                endTheReturn = new SimpleDateFormat("yyyy-MM-dd").parse(dto.getEndDate());
            }

        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        if (null == dto.getDeviceId()) {
            return null;
        }
        List<EtmDeviceMountDTO> result = etmDeviceMountMapper.getEtmDeviceMountList(dto.getDeviceId(),
                null,
                null,
                dto.getMountType(),
                startTheReturn,
                endTheReturn);
        if (result.size() > 0) {
            splitABC(result);
        }

        return PageUtils.toPageResult(result);
    }

    /**
     * 获取单个设备的异常记录
     *
     * @return
     */
    @Override
    public PageResult<EtmDeviceMountDTO> DeviceOneMount(MountDTO dto, int pageNum, int pageSize) {

        System.out.println("上传查询对象:{}" + dto);
        Date startTheReturn = null;
        Date endTheReturn = null;
        try {
            if (null != dto.getStartDate() && !"".equals(dto.getStartDate())) {
                startTheReturn = new SimpleDateFormat("yyyy-MM-dd").parse(dto.getStartDate());
            }
        } catch (Exception e) {
        }
        try {
            if (null != dto.getEndDate() && !"".equals(dto.getEndDate())) {
                endTheReturn = new SimpleDateFormat("yyyy-MM-dd").parse(dto.getEndDate());
            }
        } catch (Exception e) {
        }
        if (null == dto.getDeviceId()) {
            List<EtmDeviceMountDTO> result1 = new ArrayList<EtmDeviceMountDTO>();
            return PageUtils.toPageResult(result1);
        }
        PageHelper.startPage(pageNum, pageSize);
        List<EtmDeviceMountDTO> result = etmDeviceMountMapper.EtmDeviceMountList(dto.getDeviceId(),
                null,
                null,
                dto.getMountType(),
                startTheReturn,
                endTheReturn);
//        List<EtmDeviceMountDTO> result = etmDeviceRecordMapper.queryDeviceRunningDataByDeviceId(dto.getDeviceId());
        if (result.size() > 0) {
            splitABC(result);
        }

        return PageUtils.toPageResult(result);
    }

    /**
     * 根据登录用户获取所属设备所有的异常情况
     *
     * @param pageRequest 分页请求对象
     * @param deviceName  设备名称
     * @param deviceCode  设备编号
     * @return
     */
    @Override
    public PageResult<EtmDeviceMountDTO> pageDeviceAllMount(PageRequest pageRequest, String deviceName, String deviceCode, Integer mountType, Integer mountState, Integer typeId) {
        PageHelper.startPage(pageRequest);
        String orgIds = (String) CacheOperatorInfo.getMapValue(EtmWebUtil.userId(), null);
        List<EtmDeviceMountDTO> result = null;
        Date startTime = null;
        Date endTime = null;
        String[] split = orgIds.split(",");
        try {
            if (null != pageRequest.getQueryStartTime() && pageRequest.getQueryStartTime() != "") {
                startTime = new SimpleDateFormat("yyyy-MM-dd").parse(pageRequest.getQueryStartTime());
            }
            if (null != pageRequest.getQueryEndTime() && pageRequest.getQueryEndTime() != "") {

                endTime = new SimpleDateFormat("yyyy-MM-dd").parse(pageRequest.getQueryEndTime());
            }
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        result = etmDeviceMountMapper.getEtmDeviceMountAll(deviceName,
                deviceCode,
                split,
                null,
                startTime,
                endTime,
                mountType,
                mountState,
                typeId);
        if (result.size() > 0) {
            splitABC(result);
        }

        return PageUtils.toPageResult(result);
    }

    @Override
    public PageResult<GetAllDeviceAlarmDTO> pageTheCurrentDeviceAllMount(PageRequest pageRequest, String deviceName, String deviceCode, String deviceType, String taskCode) throws BindException {
        PageHelper.startPage(pageRequest);
        String orgIds = (String) CacheOperatorInfo.getMapValue(EtmWebUtil.userId(), null);
        if (null == orgIds) {
            throw new BindException("未登录");
        }
        List<GetAllDeviceAlarmDTO> result = null;
        try {
            Date startTime = Date.from(LocalDateTime.of(LocalDate.now(), LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant());
            Date endTime = new Date();

            result = etmDeviceMountMapper.getAllDeviceAlarm(
                    deviceName,
                    deviceCode,
                    taskCode,
                    orgIds.split(","),
                    null,
                    startTime,
                    endTime,
                    null,
                    deviceType);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        for (GetAllDeviceAlarmDTO dto : result) {
            dto.setHasPosition(toolPositionMapper.hasPosition(dto.getDeviceId(), dto.getStartTime(), dto.getEndTime(),dto.getToolTypeId()));
        }

        return PageUtils.toPageResult(result);
    }

    /**
     * 根据权限id分页查询所属设备的电池异常记录
     *
     * @param pageRequest
     * @param deviceCode
     * @param deviceName
     * @return
     */
    @Override
    public PageResult<DeviceRecordDTO> pageGetAllDevAbnormalElectricQuantity(PageRequest pageRequest, String deviceName, String deviceCode, String typeId) {
        PageHelper.startPage(pageRequest);
        List<DeviceRecordDTO> result = null;
        Date startTime = null;
        Date endTime = null;
        try {
            String orgIds = (String) CacheOperatorInfo.getMapValue(EtmWebUtil.userId(), null);
            if (null == orgIds) {
                throw new BindException("未登录");
            }
            if (null != pageRequest.getQueryStartTime() && !"".equals(pageRequest.getQueryStartTime()) && null != pageRequest.getQueryEndTime() && !"".equals(pageRequest.getQueryEndTime())) {
                startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(pageRequest.getQueryStartTime());
                endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(pageRequest.getQueryEndTime());
            }
            result = deviceMapper.getDevAbnormalelectricQuantity(orgIds.split(","),
                    deviceName,
                    deviceCode,
                    QuantityUtils.electricityPercent, typeId);
            if (result.size() > 0) {
                //对电池电量进行初始化
                Iterator<DeviceRecordDTO> it = result.iterator();
                while (it.hasNext()) {
                    DeviceRecordDTO devDTO = it.next();
                    devDTO.setAbnormalStart(devDTO.getCurrentElectricQuantity().toString());
//                    //接地线用电压判断电量
//                    if (devDTO.getDeviceType().equals(DeviceType.GroundWire)) {
//                        if (null != devDTO.getVoltage()) {
//                            BigDecimal bigDecimal = QuantityUtils.formattedQuantity(devDTO.getVoltage());
//                            devDTO.setCurrentElectricQuantity(bigDecimal);
//                        }
//                        //判断当前设备电量是否处于低电量
//                        devDTO.setAbnormalStart(QuantityUtils.powerToJudge(devDTO.getVoltage()));
//                    }
//                    //安全帽通过发送次数计算电量
//                    if (devDTO.getDeviceType().equals(DeviceType.SafetyHat)) {
//                        if (0 == devDTO.getSendCount()) {
//                            devDTO.setCurrentElectricQuantity(new BigDecimal("100.00"));
//                        }
//                        devDTO.setAbnormalStart(QuantityUtils.electricQuantityToJudge(devDTO.getCurrentElectricQuantity()));
//                    }
                }
            }
        } catch (ParseException | BindException e) {
            throw new RuntimeException(e);
        }
        PageResult<DeviceRecordDTO> page = PageUtils.toPageResult(result);
        return page;
    }

    /**
     * 分页获取单个设备的电量异常
     *
     * @param pageRequest
     * @param deviceId
     * @return
     */
    @Override
    public PageResult<DeviceRecordDTO> pageGetOneDevAbnormalElectricQuantity(PageRequest pageRequest, String deviceId) {
        PageHelper.startPage(pageRequest);
        List<DeviceRecordDTO> result = new ArrayList<DeviceRecordDTO>();
        Date startTime = null;
        Date endTime = null;
        try {
            if (null != pageRequest.getQueryStartTime() && pageRequest.getQueryStartTime() != "" && null != pageRequest.getQueryEndTime() && pageRequest.getQueryEndTime() != "") {
                startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(pageRequest.getQueryStartTime());
                endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(pageRequest.getQueryEndTime());
            }
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        result = deviceMapper.getOneDevAbnormalelectricQuantity(deviceId,
                startTime,
                endTime,
                QuantityUtils.electricityPercent);

        return PageUtils.toPageResult(result);
    }

    /**
     * @param pageRequest
     * @param devCode
     * @param devName
     * @param orgId
     * @return
     */
    @Override
    public PageResult<DeviceVO> pagegetDevList(PageRequest pageRequest,
                                               String devCode,
                                               String devName,
                                               String orgId) {
        PageHelper.startPage(pageRequest);
        Date startTime = null;
        Date endTime = null;

        try {
            if (null != pageRequest.getQueryStartTime()
                    && !"".equals(pageRequest.getQueryStartTime())
                    && null != pageRequest.getQueryEndTime()
                    && !"".equals(pageRequest.getQueryEndTime())) {
                startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(pageRequest.getQueryStartTime());
                endTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(pageRequest.getQueryEndTime());
            }
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        List<DeviceVO> result = deviceMapper.selectPages(orgId, devCode, devName, startTime, endTime);
        if (null != result && !result.isEmpty()) {
            try {
                result.stream().forEach(vo -> {
                    if (null != vo.getElectricityQuantity() && vo.getElectricityQuantity().compareTo(BigDecimal.ZERO) != 0) {
                        vo.setElectricityQuantity(QuantityUtils.formattedQuantity(vo.getElectricityQuantity()));
                    }
                });
            } catch (Exception e) {
                log.error("格式化电量异常", e);
            }
        }
        return PageUtils.toPageResult(result);
    }

    /**
     * 分页获取领用记录
     * 当state为空时获取设备所有的领用记录
     *
     * @param pageRequest
     * @param devCode
     * @param devName
     * @param state
     * @return
     */
    @Override
    public PageResult<CollectionRecord> getCollectionRecord(PageRequest pageRequest, Integer pageNum, Integer pageSize,
                                                            String devCode,
                                                            String devName,
                                                            String taskCode,
                                                            Integer typeId,
                                                            Integer state) {
        PageHelper.startPage(pageNum, pageSize);
        String orgIds = (String) CacheOperatorInfo.getMapValue(EtmWebUtil.userId(), null);
        Date startTime = null;
        Date endTime = null;
        //state 为0时查询当前未归还 为空或者为1时查询所有
        //获取未归还
        List<CollectionRecord> result = etmDeviceMountMapper.getCollectionRecord(orgIds.split(","), devCode, devName, taskCode, startTime, typeId, endTime, state);
        for (CollectionRecord re : result) {
            if (null == re.getStateName() || "".equals(re.getStateName())) {
                re.setStateName("领用中");
            }
        }
        return PageUtils.toPageResult(result);
    }

    @Override
    public PageResult<CollectionRecord> wxGetCollectionRecord(Integer pageNum, Integer pageSize,
                                                              String devCode,
                                                              String state, String currentState) {
        PageHelper.startPage(pageNum, pageSize);
        String orgIds = (String) CacheOperatorInfo.getMapValue(EtmWebUtil.userId(), null);
        //state 为0时查询当前未归还 为空或者为1时查询所有
        //获取未归还
        List<CollectionRecord> result = etmDeviceMountMapper.wxGetCollectionRecord(orgIds.split(","), devCode, null, null, state, currentState);
        for (CollectionRecord re : result) {
            if (null == re.getStateName() || "".equals(re.getStateName())) {
                re.setStateName("领用中");
            }
        }
        return PageUtils.toPageResult(result);
    }

    @Override
    public PageResult<GetByIdRecordDTO> getByIdRecord(PageRequest pageRequest,
                                                      String startDate,
                                                      String endDate,
                                                      String deviceId,
                                                      String taskCode,
                                                      Integer state) {

        Date startTime = null;
        Date endTime = null;
        Date startTheReturn = null;
        Date endTheReturn = null;
        try {
            if (null != pageRequest.getQueryStartTime()
                    && !"".equals(pageRequest.getQueryStartTime())
                    && !"null".equals(pageRequest.getQueryStartTime())) {
                startTime = new SimpleDateFormat("yyyy-MM-dd").parse(pageRequest.getQueryStartTime());
            }
            if (null != pageRequest.getQueryEndTime()
                    && !"".equals(pageRequest.getQueryEndTime())
                    && !Objects.equals(pageRequest.getQueryStartTime(), "null")) {
                endTime = new SimpleDateFormat("yyyy-MM-dd").parse(pageRequest.getQueryEndTime());
            }
            if (null != startDate && !"".equals(startDate)
                    && !Objects.equals(startDate, "null")) {
                startTheReturn = new SimpleDateFormat("yyyy-MM-dd").parse(startDate);
            }
            if (null != endDate && !"".equals(endDate)
                    && !Objects.equals(endDate, "null")) {
                endTheReturn = new SimpleDateFormat("yyyy-MM-dd").parse(endDate);
            }
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        PageHelper.startPage(pageRequest);
        List<GetByIdRecordDTO> result = etmDeviceMountMapper.getByIdRecord(startTime, endTime, startTheReturn, endTheReturn, taskCode, deviceId);
        PageResult<GetByIdRecordDTO> result1 = PageUtils.toPageResult(result);
        return result1;
    }

    /**
     * 归还工器具
     *
     * @param deviceId
     * @return
     */
    @Override
    public ApiResult<?> giveBack(String deviceId, String ticketCode) {
        int i = etmDeviceMountMapper.giveBack(deviceId, ticketCode);
        etmDeviceMountMapper.updateBack(deviceId, ticketCode);
        if (i == 0) {
            DeviceModel device = deviceMapper.selectById(deviceId);
            EtmDeviceMount etmDeviceMount = new EtmDeviceMount();
            WorkTicket workTicket = workTicketMapper.selectByTowerCode(ticketCode);
            etmDeviceMount.setDeviceTypeId(device.getTypeId());
            etmDeviceMount.setDeviceId(device.getId());
            etmDeviceMount.setDeviceCode(device.getCode());
            etmDeviceMount.setHitchAbc(null);
            etmDeviceMount.setStartTime(workTicket.getStartTime());
            etmDeviceMount.setMountState(0);
            if (null != device.getInitialLat()) {
                etmDeviceMount.setLat(device.getInitialLat().toString());
            }
            if (null != device.getInitialLng()) {
                etmDeviceMount.setLng(device.getInitialLng().toString());
            }
            if (null != device.getInitialHeight()) {
                etmDeviceMount.setHeight(device.getInitialHeight());
            }
            etmDeviceMount.setMountType(441);
            etmDeviceMount.setEndTime(new Date());
            etmDeviceMountMapper.insertAll(etmDeviceMount);
        }
        //判断是否工作票关联的工器具是否所有归还 所有归还结束工作票
        if (workTicketMapper.giveBackCount(ticketCode) == 0) {
            workTicketMapper.alterTheState(ticketCode, 2);
        }
        return ApiResult.success();
    }

    /**
     * 对设备数据进行分析处理
     */
    public Map<String, Integer> deviceDataDis(List<DeviceStatistics> ls, Map<String, Integer> map) {
        Date date = new Date();
        for (DeviceStatistics dev : ls) {
            Date createTime = dev.getCreateTime();
            int dayCount = getHourCount(createTime, date);
            //根据最新一条数据判断设备状态 最近一条数据时间间隔大于2小时表示休眠中
            if (dayCount > 2) {
                Integer xm = map.get("xm");
                xm = xm + 1;
                map.put("xm", xm);
            } else if (dayCount <= 2) {
                String hitchA = dev.getHitchA();
                String hitchB = dev.getHitchB();
                String hitchC = dev.getHitchC();
                //最新一条数据在两个小时内 并且有三项挂接状态 三项中有两项 就说明在挂接中 其他划为工作中
                if ((StringToBoolean(hitchA) ? (StringToBoolean(hitchB) || StringToBoolean(hitchC)) : (StringToBoolean(hitchB) && StringToBoolean(hitchC)))) {
                    Integer gj = map.get("gj");
                    gj = gj + 1;
                    map.put("gj", gj);
                } else {
                    Integer hx = map.get("hx");
                    hx = hx + 1;
                    map.put("hx", hx);
                }
            }
        }
        return map;
    }

    //获取两个时间相差小时
    private int getHourCount(Date date1, Date date2) {
        date1 = CalToDate(date1);
        date2 = CalToDate(date2);
        int Hours = (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600));
        return Hours;
    }

    //格式化时间
    private Date CalToDate(Date date1) {
        Calendar date = Calendar.getInstance();
        date.setTime(date1);
        int year = date.get(Calendar.YEAR);
        int mouth = date.get(Calendar.MONTH);
        int day = date.get(Calendar.DATE);
        Calendar data2 = Calendar.getInstance();
        data2.set(year, mouth, day, 23, 59, 59);
        return data2.getTime();
    }

    //String 转 Boolean String 不为空返回true 空返回 false
    private Boolean StringToBoolean(String str) {

        return str != null || !"0".equals(str.trim());
    }

    /**
     * 对三项挂接进行拆分
     *
     * @param listDto
     * @return
     */
    public List<EtmDeviceMountDTO> splitABC(List<EtmDeviceMountDTO> listDto) {
        for (EtmDeviceMountDTO dto : listDto) {
            String hitchAbc = dto.getHitchAbc();
            if (!StringUtils.isEmpty(hitchAbc)) {
                String[] split1 = hitchAbc.split(",");
                dto.setHitchA(split1[0]);
                dto.setHitchB(split1[1]);
                dto.setHitchC(split1[2]);
            }
            //判断是否有定位
            dto.setHasPosition(toolPositionMapper.hasPosition(dto.getDeviceId(), dto.getStartTime(), dto.getEndTime(),dto.getDeviceTypeId()));
        }
        return listDto;
    }

    public void startThread() {
        monitor = new Thread(monitors);
        monitor.start();
    }

    /**
     * 通讯中断监听
     */
    class Monitor implements Runnable {
        @Override
        public void run() {
            System.out.println("开启信号中断监听");
            while (true) {
                if (abnormalMap.size() >= 1) {
                    Iterator<Map.Entry<String, Long>> it = abnormalMap.entrySet().iterator();
                    while (it.hasNext()) {
                        Map.Entry<String, Long> entry = it.next();
                        Date date = new Date();
                        if(entry.getKey().startsWith("hitch")){
                            //判断是否在三分钟内 挂接齐全
                            if ((date.getTime() - entry.getValue()) > 180000) {

                                //AddAbnormal(entry.getKey().replaceAll("hitch",""), 0);
                            }
                        }else {
                            //判断上次上次时间与当前时间 是否相差
                            if ((date.getTime() - entry.getValue()) > time) {
                                AddAbnormal(entry.getKey(), 321);
                            }
                        }

                    }
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

}